package com.oneraku.service.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.oneraku.service.exceptions.InfoException;
import com.oneraku.service.exceptions.MissParameterException;
import com.oneraku.service.utils.R;
import com.oneraku.service.utils.RequestBean;
import com.oneraku.service.utils.RequestBeanUtils;
import com.oneraku.service.utils.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: hui.ren@huberbuy.com
 * @Date: 2019-08-27 11:20
 */
@Aspect
@Component
@Slf4j
public class ControllerLogAspectConfig {
    private final ObjectMapper mapper;

    @Autowired
    public ControllerLogAspectConfig(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Pointcut("execution(public * com.oneraku.service.controller.*.*(..))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        try{
            Object result = joinPoint.proceed();
            for (Object object : joinPoint.getArgs()) {
                if (
                        object instanceof MultipartFile
                                || object instanceof HttpServletRequest
                                || object instanceof HttpServletResponse
                                || object instanceof Exception
                ) {
                    continue;
                }
                log.info(object.getClass().getName());
                String mapperObj = mapper.writeValueAsString(object);
                Object mapperObb;
                if (mapperObj.startsWith("{")) {
                    mapperObb = JSONObject.parseObject(mapperObj);
                } else if (mapperObj.startsWith("[")) {
                    mapperObb = JSONObject.parseArray(mapperObj);
                } else {
                    mapperObb = mapperObj;
                }
                RequestBean requestBean = RequestBeanUtils.get();
                requestBean.setDuration(System.currentTimeMillis() - start);
                requestBean.setParameter(mapperObb);
                requestBean.setResult(result);
            }
            return result;
        }catch (Exception exception){
            if(exception instanceof HttpRequestMethodNotSupportedException){
                return R.failed(ResultCode.METHOD_NOT_ALLOWED);
            } else if(exception instanceof HttpMessageNotReadableException){
                return R.failed(ResultCode.BAD_REQUEST);
            } else if(exception instanceof MissParameterException){
                return ((MissParameterException)exception).getResult();
            } else if(exception instanceof InfoException){
                return ((InfoException)exception).getResult(exception.getMessage());
            } else {
                exception.printStackTrace();
                return R.failed(ResultCode.SYSTEM_ERR);
            }
        }
    }
}
